package com.hly.tool.tree;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hly.tool.list.ListUtil;

import java.util.List;
import java.util.Map;


/**
 * 数据层级类型
 * <p>
 * 层次
 * 1
 * .2
 * .2
 * 1
 * .2
 * .2
 * 1
 * .2
 * .2
 * .2
 * .2
 * .2
 * ..3
 * ..3
 */
public class Tree1
{



    /**
     * 获取树结构 json 数据
     *
     * @param list
     * @return
     */
    public static JSONObject getTreeJSONObject(List<Map<String, String>> list, String levelColumn) throws Exception
    {
        JSONObject oneTree = getTreeData(list, null, levelColumn);
        return oneTree;
    }


    /**
     * 获取树结构 json 数据
     * @param lists
     * @return
     */
    public static String getTreeStr (List<List> lists, String levelColumn) throws Exception {
        return  getTreeJSONArray(lists,  levelColumn).toJSONString();
    }

    /**
     * 获取树结构 json 数据
     *
     * @param lists
     * @return
     */
    public static JSONArray getTreeJSONArray(List<List> lists, String levelColumn) throws Exception
    {

        JSONArray array = new JSONArray();
        for (int i = 0; i < lists.size(); i++)
        {
            List list = lists.get(i);
            JSONObject oneTree = getTreeData(list, null,levelColumn);
//            System.out.println("oneTree = " + responseFormat(oneTree));
            array.add(oneTree);
        }

        return array;
    }


    /**
     * @param array
     * @param jsonObject
     * @return
     * @throws Exception
     */
    private static String getLevelData(List<Map<String, String>> list, JSONArray array, JSONObject jsonObject,String levelColumn) throws Exception
    {
        JSONObject treeData = getTreeData(list, null,levelColumn);
        return treeData.toString();
    }


    /**
     * 获取顶层的数据
     *
     * @param list
     * @param json
     * @return
     */
    private static JSONObject getTreeData(List<Map<String, String>> list, JSONObject json,String levelColumn)
    {
        String mapVal = "1";
        if (json == null)
        {
            json = new JSONObject();
        } else
        {
            mapVal = json.getString(levelColumn);
            if (mapVal == null)
            {
                return new JSONObject();
            }
        }
        List<Integer> indexList = ListUtil.getIndexListByMapValue(list, levelColumn,mapVal);
        if (indexList.size() > 0 && mapVal.equals("1"))
        {
            int index = indexList.get(0);
            Map<String, String> map0 = list.get(index);
            String jsonStr_0 = JSONObject.toJSONString(map0);
            json = JSONObject.parseObject(jsonStr_0);
            json.put("index", 0);
        }
        JSONArray children = getChildren(list, json,levelColumn);
        json.put("children", children);
        for (int i = 0; i < children.size(); i++)
        {
            JSONObject json_i = children.getJSONObject(i);
            getTreeData(list, json_i,levelColumn);
        }
        return json;
    }


    /**
     * @param list
     * @param json
     * @return
     */
    private static JSONArray getChildren(List<Map<String, String>> list, JSONObject json,String levelColumn)
    {
        JSONArray array = new JSONArray();
        if (json == null || json.isEmpty())
        {
            return array;
        }

        //获取当前数据在集合中的下角标
        int index = json.getInteger("index");

        //获取当前数据的层级
        String level = json.getString(levelColumn);

        //获取当前数据的子层级
        String nextLevel = getNextLevel(level);

        //获取子层级数据的下角标集合
        List<Integer> indexList = ListUtil.getIndexListByMapValue(list, level, nextLevel, index);


        for (int i = 0; i < indexList.size(); i++)
        {
            int index_i = indexList.get(i);
            Map<String, String> map_index = list.get(index_i);
            JSONObject json_index = JSONObject.parseObject(JSONObject.toJSONString(map_index));
            json_index.put("index", index_i);
            array.add(json_index);
        }
        return array;
    }


    /**
     * 获取下一个层级
     *
     * @param level
     * @return
     */
    private static String getNextLevel(String level)
    {
        String str_templevel = level.substring(level.length() - 1);
        int i_templevel = Integer.parseInt(str_templevel) + 1;
        int len = level.length();
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < len; i++)
        {
            buffer.append(".");
        }
        buffer.append(i_templevel);
        String nextLevel = buffer.toString();
        return nextLevel;
    }


    /**
     * @param json
     * @return String
     * @throws
     * @Description format json data
     * @author
     * @date 2018/10/29-13:45
     */
    public static String responseFormat(JSONObject json)
    {
        return responseFormat(json.toString());
    }


    /**
     * @param array
     * @return String
     * @throws
     * @Description format json data
     * @author
     * @date 2018/10/29-13:45
     */
    public static String responseFormat(JSONArray array)
    {
        return responseFormat(array.toString());
    }


    /**
     * @param resString
     * @return String
     * @throws
     * @Description format json data
     * @author
     * @date 2018/10/29-13:45
     */
    public static String responseFormat(String resString)
    {
        StringBuffer jsonForMatStr = new StringBuffer();
        int level = 0;
        for (int index = 0; index < resString.length(); index++)//
        {
            char c = resString.charAt(index);
            if (level > 0 && '\n' == jsonForMatStr.charAt(jsonForMatStr.length() - 1))
            {
                jsonForMatStr.append(getLevelStr(level));
            }
            switch (c)
            {
                case '{':
                case '[':
                    jsonForMatStr.append(c + "\n");
                    level++;
                    break;
                case ',':
                    jsonForMatStr.append(c + "\n");
                    break;
                case '}':
                case ']':
                    jsonForMatStr.append("\n");
                    level--;
                    jsonForMatStr.append(getLevelStr(level));
                    jsonForMatStr.append(c);
                    break;
                default:
                    jsonForMatStr.append(c);
                    break;
            }
        }
        return jsonForMatStr.toString();
    }


    /**
     * @param level
     * @return
     * @throws
     * @author
     * @date
     */
    public static String getLevelStr(int level)
    {
        StringBuffer levelStr = new StringBuffer();
        for (int levelI = 0; levelI < level; levelI++)
        {
            levelStr.append("\t");
        }
        return levelStr.toString();
    }

}
